package com.spider.service;

import com.spider.entites.Filed;
import com.spider.entites.Task;
import com.spider.mapper.TaskMapper;
import com.spider.utils.ExcelExportUtils;
import com.spider.utils.JsonUtils;
import com.spider.utils.StringUtils;
import com.spider.vo.BarVo;
import com.spider.vo.DataVo;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author panglin
 * @date 2020/11/22 9:54
 */
@Service
public class DataService {

    @Resource
    private QueryRunner queryRunner;

    @Resource
    private TaskMapper taskMapper;

    public DataVo queryAll(String condition, Integer size, Integer num) {
        if (StringUtils.isEmpty(condition)) {
            return null;
        }
        Task task = this.taskMapper.queryTaskByTaskName("%"+condition+"%");
        if (task != null) {
            DataVo dataVo = new DataVo();
            List<Filed> listPageFiled = JsonUtils.transformJsonToListFiled(task.getListFiled());
            List<Filed> detailPageFiled = JsonUtils.transformJsonToListFiled(task.getDetailFiled());
            if (!CollectionUtils.isEmpty(detailPageFiled)) {
                listPageFiled.addAll(detailPageFiled);
            }
            dataVo.setFiled(listPageFiled);
            Filed filed = new Filed();
            filed.setFiled("createTime");
            listPageFiled.add(filed);
            dataVo.setTotal(task.getSpiderNum());
            dataVo.setData(this.getList(listPageFiled, task.getTbName(), size, num,true));
            return dataVo;
        }
        return null;
    }

    /**
     * 获取数据
     * @param filedList
     * @param tbName
     * @param size
     * @param num
     * @param pageAble
     * @return
     */
    private List<Map<String, String>> getList(List<Filed> filedList, String tbName, Integer size, Integer num,Boolean pageAble) {
        if (pageAble){
            num = (num - 1) * size;
        }
        StringBuilder sql = new StringBuilder("select ");
        for (Filed f : filedList) {
            sql.append(f.getFiled()).append(",");
        }
        sql = new StringBuilder(sql.substring(0, sql.length() - 1));
        sql.append(" from ").append(tbName).append(" limit ").append(num).append(",").append(size);
        List<Map<String, String>> mapList = null;
        try {
            mapList = this.queryRunner.query(sql.toString(), rs -> {
                List<Map<String, String>> list = new ArrayList<>();
                while (rs.next()) {
                    Map<String, String> map = new LinkedHashMap<>();
                    for (Filed f : filedList) {
                        map.put(f.getFiled(), rs.getString(f.getFiled()));
                    }
                    list.add(map);
                }
                return list;
            });
        } catch (SQLException throwable) {
            throwable.printStackTrace();
        }
        return mapList;
    }

    /**
     * 导出数据（Excel）
     * @param taskName
     * @return
     */
    public ResponseEntity<byte[]> export(String taskName) {
        Task task = this.taskMapper.queryTaskByTaskName(taskName);
        if (task == null){
            return ResponseEntity.notFound().build();
        }
        List<Filed> list = JsonUtils.transformJsonToListFiled(task.getListFiled());
        List<Filed> detail = JsonUtils.transformJsonToListFiled(task.getDetailFiled());
        if (detail!=null){
            list.addAll(detail);
        }
        Filed filed = new Filed();
        filed.setFiled("createTime");
        list.add(filed);
        List<Map<String, String>> data = this.getList(list, task.getTbName(), task.getSpiderNum(), 0,false);
        return ExcelExportUtils.export(taskName, list, data);
    }

    /**
     * 获取柱状图数据
     * @return
     */
    public BarVo getBarData() {
        List<Task> data = this.taskMapper.getDataForBar();
        if (CollectionUtils.isEmpty(data)){
            return new BarVo(null, null,null,404);
        }
        List<String> names = new ArrayList<>();
        List<Integer> nums = new ArrayList<>();
        List<Long> times = new ArrayList<>();
        data.forEach(t->{
            names.add(t.getTaskName());
            nums.add(t.getSpiderNum());
            times.add((t.getEndTime().getTime()-t.getBeginTime().getTime())/1000);
        });
        return new BarVo(names, nums,times, 200);
    }
}
